// main.cpp
#include <Arduino.h>
#include <NimBLEDevice.h>
#include <NimBLEHIDDevice.h>
#include <NimBLEServer.h>
#include "BleKeyboard.h"
#include "BleMouse.h"
#include "BleMedia.h"
#include "HIDReportMap.h"

NimBLEHIDDevice* hid;
NimBLEAdvertising* advertising;

BleKeyboard bleKeyboard;
BleMouse bleMouse;
BleMedia bleMedia;

class ServerCallbacks : public NimBLEServerCallbacks {
  void onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo) override {
    Serial.println("✅ 已连接");
  }
  void onDisconnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo, int reason) override {
    Serial.printf("🔌 已断开（reason=%d），重新广播\n", reason);
    NimBLEDevice::startAdvertising();
  }
};

void setup() {
  Serial.begin(115200);
  NimBLEDevice::init("ESP32 Combo HID");
  NimBLEDevice::setSecurityAuth(true, true, true);
  NimBLEDevice::setSecurityIOCap(BLE_HS_IO_NO_INPUT_OUTPUT);
  NimBLEDevice::setOwnAddrType(BLE_OWN_ADDR_PUBLIC);

  NimBLEServer* pServer = NimBLEDevice::createServer();
  pServer->setCallbacks(new ServerCallbacks());

  hid = new NimBLEHIDDevice(pServer);
  hid->setManufacturer("OpenAI");
  hid->setBatteryLevel(100);
  hid->setPnp(0x02, 0xe502, 0xa111, 0x0210);
  hid->setHidInfo(0x00, 0x01);

  // 注册键盘描述
  hid->setReportMap((uint8_t*)reportMap, reportMapSize);

  bleKeyboard.begin(hid);
  bleMouse.begin(hid);
  bleMedia.begin(hid);

  hid->startServices();

  advertising = NimBLEDevice::getAdvertising();
  // advertising->setAppearance(0x03C0);
  advertising->setAppearance(0x03C1);
  advertising->addServiceUUID(hid->getHidService()->getUUID());

  NimBLEAdvertisementData scanData;
  scanData.setName("ESP32 Combo HID");
  advertising->setScanResponseData(scanData);

  advertising->start();
  Serial.println("✅ BLE Combo HID 启动成功！");
}

void loop() {
  static uint32_t t = 0;
  if (millis() - t > 5000) {
    t = millis();
    bleKeyboard.sendKey(0x08); // 'e'
    delay(1000);
    bleKeyboard.sendKey(0x12); // 'o'
    delay(1000);
    bleKeyboard.sendKey(0x2C); // space
    delay(1000);
    bleKeyboard.sendKey(0x04); // space
    delay(1000);
    bleMouse.move(10, 0);
    delay(1000);
    bleMedia.send(0b001);
  }
}
